﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections;
using System.Text;
using System.Threading.Tasks;

using App.Core.Data; 
using App.Core.Data.Repositories;
using App.Core.Entities.Foundation;
using App.Data.Repositories;

namespace App.Data
{
    public class UnitOfWork : IUnitOfWork
    {
        private readonly IDbContext context;
        private bool disposed;
        private Hashtable repositories;
        public UnitOfWork(IDbContext context)
        {
            this.context = context;
        }
        public void BeginTransaction()
        {
            context.BeginTransaction();
        }

        public int Commit()
        {
            return context.Commit();
        }

        public Task<int> CommitAsync()
        {
            return context.CommitAsync();
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        public void Dispose(bool disposing)
        {
            if (!disposed && disposing)
            {
                context.Dispose();
                foreach (IDisposable repository in repositories.Values)
                {
                    repository.Dispose();
                }
            }
            disposed = true;
        }

        public IRepository<TEntity> Repository<TEntity>() where TEntity : class
        {
            if (repositories == null)
            {
                repositories = new Hashtable();
            }

            var type = typeof(TEntity).Name;

            if (repositories.ContainsKey(type))
            {
                return (IRepository<TEntity>) repositories[type];
            }

            var repositoryType = typeof(BaseRepository<>);

            repositories.Add(type, Activator.CreateInstance(repositoryType.MakeGenericType(typeof(TEntity)), context));

            return (IRepository<TEntity>) repositories[type];
        }

        public void Rollback()
        {
            context.Rollback();
        }
    }
}
